
/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , http = require('http')
  , path = require('path')
  , model = require('./models');

var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);

app.configure(function(){
  app.set('port', process.env.PORT || 80);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser({uploadDir:'./uploads'}));
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

routes(app);
server.listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});
var messageStatus={
  inMessage:0,
  /*
    对方发来的信息
  */
  onSend:1,
  /*
    信息发送中
  */
  sendSuccess:2,
  /*
    信息发送成功,指被服务器接收
  */
  sendFailed:3,
  /*
    信息发送失败,等待用户选择重发或删除
  */
  deleted:4,
  /*
    信息发送失败后被用户删除
  */
  received:5,
  /*
    信息已被对方接收
  */
  read:6
  /*
    信息已被对方查看
  */
}
var userModel = model.userModel;
var errorModel = model.errorModel;
var questionModel = model.questionModel;
var pieTime = function(){
  var curTime = new Date();
  var year = curTime.getFullYear();
  var month = curTime.getMonth()+1;
  if(month<10){
    month = '0'+month;
  }
  var date = curTime.getDate();
  if(date<10){
    date = '0'+date;
  }
  var hour = curTime.getHours();
  if(hour<10){
    hour = '0'+hour;
  }
  var minute = curTime.getMinutes();
  if(minute<10){
    minute = '0'+minute;
  }
  var second = curTime.getSeconds();
  if(second<10){
    second = '0'+second;
  }
  var result = year+'-'+month+'-'+date+' '+hour+':'+minute+':'+second;
  return result;
}
var logError=function(err,reason){
  var newErr = new errorModel({
    'err':JSON.stringify(err),
    'reason':reason,
    'time':pieTime()
  });
  newErr.save()
}
io.on('connection',function(socket){
  var puid = null;   //当前连接对应唯一用户的puid
  var verified=false;  //标记当前连接是否经过验证,若为false不响应任何请求
  socket.emit('connected');
  socket.on('login',function(data){
    /*
      此处需要对用户进行验证
    */
    verified=true;
    if(puid){return;}
    puid = data.puid;
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'登录查找用户出错:'+puid);
        return;
      }
      if(user){
        if(user.socketId){
          var lastSocket = io.sockets.sockets[user.socketId];
          if(lastSocket){
            lastSocket.emit('dump');
          }
        }
        user.platform = data.platform;
        user.socketId = socket.id;
        user.messageReplied = 1;
        user.save(function(err){
          if(err){
            logError(err,'用户登录之后记录状态出错:'+puid);
            return;
          }
          if(user.messageReplied&&user.curContactIndex<user.contacts.length
            &&user.contacts[user.curContactIndex].nextMessageIndex<user.contacts[user.curContactIndex].messageList.length){
            var newMessage = user.contacts[user.curContactIndex].messageList[user.contacts[user.curContactIndex].nextMessageIndex];
            user.messageReplied=0;
            user.save(function(err){
              if(err){
                logError(err,'用户登录并发送消息出错:'+puid);
              }
              socket.emit('pieMessage',{
                'from':user.contacts[user.curContactIndex].targetId,
                'content':newMessage,
                'mid':user.contacts[user.curContactIndex].nextMessageIndex
              });
            });
          }
        })
      }
      else{
        var newUser  = new userModel({
          'puid':data.puid,
          'sex':data.sex,
          'platform':data.platform,
          'socketId':socket.id,
          'curContactIndex':0,
          'messageReplied':1,
          'contacts':[]
        })
        newUser.save(function(err){
          if(err){
            logError(err,'新用户保存出错:'+data.puid);
          }
        });
      }
    })
  });
  socket.on('pieTalk',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'pieTalk查找用户出错:'+puid);
        return;
      }
      if(user){
        userModel.findOne({'puid':data.targetId},function(err,target){
          if(err){
            logError(err,'pieTalk查找目标用户出错:'+data.targetId);
            return;
          }
          var thisMessage = {
            'status': messageStatus.sendSuccess,
            'contentType': data.contentType,
            'content': data.content,
            'time': pieTime()
          };
          if(user.curContactIndex >= user.contacts.length
            ||user.contacts[user.curContactIndex].targetId != data.targetId){
            var goal = -1;
            for(var i = user.contacts.length-1; i >= 0; i--){
              if(user.contacts[i].targetId == data.targetId){
                goal = i;
                break;
              }
            }
            if(goal>=0){
              user.curContactIndex = goal;
            }
            else{
              user.curContactIndex = user.contacts.length;
              user.contacts.push({
                targetId:data.targetId,
                nextMessageIndex:0,
                messageList:[]
              });
            }
          }
          user.contacts[user.curContactIndex].nextMessageIndex = user.contacts[user.curContactIndex].messageList.push(thisMessage);
          user.save(function(err){
            if(err){
              logError(err,'用户发送消息被服务器接收后,用户保存状态出错'+puid);
              return;
            }
            socket.emit('messageSendSuccess',{
              'mid':user.contacts[user.curContactIndex].nextMessageIndex-1
            });
          });
          thisMessage.status = messageStatus.inMessage;
          if(target){
            if(target.curContactIndex >= target.contacts.length
              ||target.contacts[target.curContactIndex].targetId != puid){
              var goal = -1;
              for(var i = target.contacts.length-1; i >= 0; i--){
                if(target.contacts[i].targetId == puid){
                  goal = i;
                  break;
                }
              }
              if(goal>=0){
                target.curContactIndex = goal;
              }
              else{
                target.curContactIndex = target.contacts.length;
                target.contacts.push({
                  targetId:puid,
                  nextMessageIndex:0,
                  messageList:[]
                });
              }
            }
            target.contacts[target.curContactIndex].messageList.push(thisMessage);
            target.save(function(err){
              if(err){
                logError(err,'用户发送消息后对方保存出错'+data.targetId);
                return;
              }
              if(target.messageReplied&&target.socketId
                &&target.contacts[target.curContactIndex].nextMessageIndex<target.contacts[target.curContactIndex].messageList.length){
                var newMessage = target.contacts[target.curContactIndex].messageList[target.contacts[target.curContactIndex].nextMessageIndex];
                var targetSocket = io.sockets.sockets[target.socketId];
                if(targetSocket){
                  target.messageReplied=0;
                  target.save(function(err){
                    if(err){
                      logError(err,'用户发送消息后对方保存出错'+data.targetId);
                      return;
                    }
                    targetSocket.emit('pieMessage',{
                      'from':puid,
                      'content':newMessage,
                      'mid':target.contacts[target.curContactIndex].nextMessageIndex
                    });
                  })
                }
              }
            });
          }
          else{
            var newUser  = new userModel({
              'puid':data.targetId,
              'socketId':null,
              'curContactIndex':0,
              'messageReplied':1,
              'contacts':[{
                targetId:puid,
                nextMessageIndex:0,
                messageList:[thisMessage]
              }]
            });
            newUser.save(function(err){
              if(err){
                logError(err,'用户发送消息后对方新建用户保存出错:'+data.targetId);
              }
            })
          }
        })
      }
    });
  });
  socket.on('messageReceived',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'接收消息时查找用户出错:'+puid);
        return;
      }
      if(user){
        if(user.contacts[user.curContactIndex].targetId != data.targetId){
          var goal = -1;
          for(var i = user.contacts.length-1; i >= 0; i--){
            if(user.contacts[i].targetId == data.targetId){
              goal = i;
              break;
            }
          }
          if(goal<0){
            logError('something error happened here');
            return;
          }
          else{
            user.curContactIndex = goal;
          }
        }
        if(user.contacts[user.curContactIndex].messageReplied||data.mid != user.contacts[user.curContactIndex].nextMessageIndex){return;}
        user.messageReplied = 1;
        user.contacts[user.curContactIndex].nextMessageIndex = data.mid+1;
        userModel.findOne({'puid':user.contacts[user.curContactIndex].targetId},function(err,target){
          if(err){
            logError(err,'接收消息时查找消息来源用户出错:'+from);
            return;
          }
          if(target){
            if(target.curContactIndex >= target.contacts.length
              ||target.contacts[target.curContactIndex].targetId != puid){
              var goal = -1;
              for(var i = target.contacts.length-1; i >= 0; i--){
                if(target.contacts[i].targetId == puid){
                  goal = i;
                  break;
                }
              }
              if(goal>=0){
                target.curContactIndex = goal;
              }
              else{
                logError('what a fuck!');
                return;
              }
            }
            target.contacts[target.curContactIndex].messageList[data.mid].status = messageStatus.received;
            target.save(function(err){
              if(err){
                logError(err,'接收消息时消息来源用户保存状态出错:'+targetId);
              }
              if(target.socketId){
                var targetSocket = io.sockets.sockets[target.socketId];
                if(targetSocket){
                  targetSocket.emit('messageReceived',{
                    'mid':data.mid
                  });
                }
              }
            })
          }
        });
        user.save(function(err){
          if(err){
            logError(err,'接收消息后用户保存状态出错'+puid);
            return;
          }
          if(user.messageReplied&&user.contacts[user.curContactIndex].nextMessageIndex<user.contacts[user.curContactIndex].messageList.length){
            var newMessage = user.contacts[user.curContactIndex].messageList[user.contacts[user.curContactIndex].nextMessageIndex];
            user.messageReplied=0;
            user.save(function(err){
              if(err){
                logError(err,'接收消息后用户保存状态出错'+puid);
                return;
              }
              socket.emit('pieMessage',{
                'from':user.contacts[user.curContactIndex].targetId,
                'content':newMessage,
                'mid':user.contacts[user.curContactIndex].nextMessageIndex
              });
            })
          }
        })
      }
    });
  });
  socket.on('messageRead',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'接收消息时查找用户出错:'+puid);
        return;
      }
      if(user){
        if(user.contacts[user.curContactIndex].targetId != data.targetId){
          var goal = -1;
          for(var i = user.contacts.length-1; i >= 0; i--){
            if(user.contacts[i].targetId == data.targetId){
              goal = i;
              break;
            }
          }
          if(goal<0){
            logError('something error happened here');
            return;
          }
          else{
            user.curContactIndex = goal;
          }
        }
        userModel.findOne({'puid':user.contacts[user.curContactIndex].targetId},function(err,target){
          if(err){
            logError(err,'接收消息时查找消息来源用户出错:'+from);
            return;
          }
          if(target){
            if(target.curContactIndex >= target.contacts.length
              ||target.contacts[target.curContactIndex].targetId != puid){
              var goal = -1;
              for(var i = target.contacts.length-1; i >= 0; i--){
                if(target.contacts[i].targetId == puid){
                  goal = i;
                  break;
                }
              }
              if(goal>=0){
                target.curContactIndex = goal;
              }
              else{
                logError('what a fuck!');
                return;
              }
            }
            if(target.contacts[target.curContactIndex].messageList[data.mid].status == messageStatus.read){return;}
            target.contacts[target.curContactIndex].messageList[data.mid].status = messageStatus.read;
            target.save(function(err){
              if(err){
                logError(err,'接收消息时消息来源用户保存状态出错:'+targetId);
              }
              if(target.socketId){
                var targetSocket = io.sockets.sockets[target.socketId];
                if(targetSocket){
                  targetSocket.emit('messageRead',{
                    'mid':data.mid
                  });
                }
              }
            })
          }
        });
      }
    });
  });
  socket.on('askQuestion',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'提问时查找用户出错'+puid);
        return;
      }
      if(user){
        console.log('用户:'+puid+'提问:'+data.title);
        var curTime = new Date();
        var newQuestion = new questionModel({
          'title':data.title,
          'type':data.type,
          'author':puid,
          'comments':[],
          'year':curTime.getFullYear(),
          'month':curTime.getMonth()+1,
          'date':curTime.getDate()
        });
        newQuestion.save(function(err){
          if(err){
            logError('用户:'+puid+'发布提问出错:'+err);
          }
          else{
            user.questions.push(newQuestion._id);
            user.save(function(err){
              if(err){
                logError('用户:'+puid+'保存提问信息出错:'+err)
              }
              else{
                socket.emit('putQuestionSuccess',{'id':newQuestion._id});
              }
            })
          }
        })
      }
    });
  });
  socket.on('disconnect',function(){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'disconnect时查找用户出错'+puid);
        return;
      }
      if(user){
        if(socket.id == user.socketId){
          user.socketId = null;
          user.save(function(err){
            if(err){
              logError(err,'disconnect后用户保存状态出错:'+puid);
            }
          })
        }
      }
    });
  });
  socket.on('talkToNpc',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'talkToNpc查找用户出错:'+puid);
        return;
      }
      if(user){
        var thisMessage = {
          'from': puid,
          'content': data.content,
          'time': pieTime()
        };
        user.npcTalk.push(thisMessage);
        user.save(function(err){
          if(err){
            logError(err,'talkToNpc保存用户出错:'+puid);
          }
        })
      }
    });
  })
  socket.on('npcReply',function(data){
    if(!verified){return;}
    userModel.findOne({'puid':puid},function(err,user){
      if(err){
        logError(err,'npcReply查找用户出错:'+puid);
        return;
      }
      if(user){
        var thisMessage = {
          'from': '小Pie',
          'content': data.content,
          'time': pieTime()
        };
        user.npcTalk.push(thisMessage);
        user.save(function(err){
          if(err){
            logError(err,'npcReply保存用户出错:'+puid);
          }
        })
      }
    });
  })
});